/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
/**
 *
 */
package org.unidata.mdm.rest.data.converter;

import java.util.List;

import org.unidata.mdm.core.type.data.DataRecord;
import org.unidata.mdm.core.type.data.RecordStatus;
import org.unidata.mdm.core.type.data.impl.SerializableDataRecord;
import org.unidata.mdm.data.type.data.EtalonRecord;
import org.unidata.mdm.data.type.data.EtalonRecordInfoSection;
import org.unidata.mdm.rest.data.ro.EtalonRecordRO;
import org.unidata.mdm.system.util.ConvertUtils;

/**
 * @author Mikhail Mikhailov Golden record to REST golden record converter.
 */
public class DataRecordEtalonConverter {

    /**
     * Constructor.
     */
    private DataRecordEtalonConverter() {
        super();
    }

    /**
     * Converts a golden record to a REST golden record.
     * @param record the record
//     * @param errors errors occurred, may be null
     * @param duplicates duplicates which may possibly exist
     * @return REST
     */
    public static EtalonRecordRO to(EtalonRecord record,
                                    //todo DQ_FRAGMENT List<DQDataRecordError> errors,
                                    List<String> duplicates) {

        if (record == null) {
            return null;
        }

        EtalonRecordRO result = new EtalonRecordRO();

        result.setDuplicateIds(duplicates);

        // Informational
        EtalonRecordInfoSection info = record.getInfoSection();
        if (info != null) {
            // Key
            result.setEtalonId(info.getEtalonKey().getId());

            result.setStatus(info.getStatus() != null ? info.getStatus().name() : RecordStatus.ACTIVE.name());
            result.setValidFrom(ConvertUtils.date2LocalDateTime(info.getValidFrom()));
            result.setValidTo(ConvertUtils.date2LocalDateTime(info.getValidTo()));
            result.setCreateDate(info.getCreateDate());
            result.setUpdateDate(info.getUpdateDate());
            result.setEntityName(info.getEntityName());
            result.setCreatedBy(info.getCreatedBy());
            result.setUpdatedBy(info.getUpdatedBy());

            result.setGsn(info.getEtalonKey().getLsn() == null ? null : info.getEtalonKey().getLsn().toString());

            result.setOperationType(info.getOperationType() != null ? info.getOperationType().name() : null);
        }

        // Attributes
        SimpleAttributeConverter.to(record.getSimpleAttributes(), result.getSimpleAttributes());
        ComplexAttributeConverter.to(record.getComplexAttributes(), result.getComplexAttributes());
        result.getCodeAttributes().addAll(CodeAttributeConverter.to(record.getCodeAttributes()));
        result.getArrayAttributes().addAll(ArrayAttributeConverter.to(record.getArrayAttributes()));

        // TODO: 23.10.2019 DQ_FRAGMENT
        //copyDQErrors(errors, result.getDqErrors());

        return result;
    }

    /**
     * System to REST list converter.
     * @param source the source
     * @param target the target
     */
    public static void to(List<EtalonRecord> source, List<EtalonRecordRO> target) {
        if (source == null) {
            return;
        }

        for (EtalonRecord r : source) {
            target.add(to(r, null));
        }
    }

    /**
     *
     * @param record
     * @return
     */
    public static DataRecord from(EtalonRecordRO record) {

        if (record == null) {
            return null;
        }

        SerializableDataRecord result = new SerializableDataRecord(
                record.getSimpleAttributes().size() +
                record.getCodeAttributes().size() +
                record.getArrayAttributes().size() +
                record.getComplexAttributes().size() + 1);

        result.addAll(SimpleAttributeConverter.from(record.getSimpleAttributes()));
        result.addAll(CodeAttributeConverter.from(record.getCodeAttributes()));
        result.addAll(ArrayAttributeConverter.from(record.getArrayAttributes()));
        result.addAll(ComplexAttributeConverter.from(record.getComplexAttributes()));

        return result;
    }

    /**
     * Converts DQ errors.
     * @param errors the source
     * @param target the target
     */
//    public static void copyDQErrors(List<DQDataRecordError> errors, List<DQErrorRO> target) {
//
//        if (CollectionUtils.isEmpty(errors)) {
//            return;
//        }
//
//        for (DQDataRecordError sourceError : errors) {
//            target.add(toDQErrorRO(sourceError));
//        }
//    }

    /**
     * Convert DQ error
     * @param sourceError source
     * @return target
     */
//    public static DQErrorRO toDQErrorRO(DQDataRecordError sourceError) {
//
//        DQErrorRO targetError = new DQErrorRO();
//        targetError.setCategory(sourceError.getCategory());
//        targetError.setMessage(sourceError.getMessage());
//        targetError.setRuleName(sourceError.getRuleName());
//        targetError.setSeverity(sourceError.getSeverity());
//        targetError.setPaths(sourceError.getValues().stream().map(Pair::getKey).collect(Collectors.toList()));
//        // TODO: 23.10.2019 classifiers build path
//        //targetError.setPaths(sourceError.getValues().stream().map(Pair::getKey).map(s -> sourceError.buildPath(s)).collect(Collectors.toList()));
//
//        return targetError;
//    }
}
